/*******************************************************************************
 *	                           bsp ram clear.c
 *******************************************************************************/
#include "bsp.h"
#include "bsp_spi_nor.h"
#include "pincfg.h"
#include "nor_cmd.h"
#include "framework.h"

#define NOR_SPI SPI1
#define ISR_IRQn SPI1_IRQn

uint8_t b_io_q_mode = 0;
extern const spi_flash_hal_type spi_nor;
extern SPI_HandleTypeDef hspi1;

/*****************************************************************************
 * @brief   hal init.
 *
 * @param   none
 *
 * @return  none
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void nor_spi_init(void)
{
	NOR_SPI->CR1 |= SPI_CR1_SPE;
	
	nor_spi_cs(0);

	nor_spi_rb();

	nor_spi_cs(1);

	b_io_q_mode = 0;
	
	nor_init(&spi_nor, 0);
}

/*****************************************************************************
 * @brief   cs ctr.
 * @param   st
 * @return  none
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void nor_spi_cs(uint8_t st)
{
	// CONFIG :: SPI_NSS_HARD_OUTPUT
	if (st)
	{
		// cs out high @ SPI disabled
		spi_cs.en();
		//NOR_SPI->CR1 &= ~SPI_CR1_SPE;
		NOP20();
	}
	else
	{
		// cs out low @ SPI enabled
		spi_cs.dis();
		//NOR_SPI->CR1 |= SPI_CR1_SPE;
		NOP20();
	}
}

/*****************************************************************************
 * @brief   spi mode select.
 *****************************************************************************/
void nor_hal_mode_spi(void) { b_io_q_mode = 0; };
void nor_hal_mode_qpi_out(void) { b_io_q_mode = 1; };
void nor_hal_mode_qpi_in(void) { b_io_q_mode = 1; };

/*****************************************************************************
 * @brief   spi speed.
 *****************************************************************************/
void nor_spi_high_speed(void)
{
}

/*****************************************************************************
 * @brief   spi speed.
 *****************************************************************************/
void nor_spi_low_speed(void)
{
}

/*****************************************************************************
 * @brief   spi delay.
 *****************************************************************************/
__STATIC_INLINE void spi_read_delay(void) {NOP8();}
__STATIC_INLINE int is_spi_rx_ready(SPI_TypeDef *spix) {return ((spix->SR & SPI_SR_RXWNE) != 0);};
__STATIC_INLINE void spi_rx_reset(SPI_TypeDef *spix)  {             
	while (is_spi_rx_ready(spix))        
	{                                   
		volatile uint32_t rd = spix->RXDR; 
	}
}
__STATIC_INLINE int is_spi_busy(SPI_TypeDef *spix) {return (0 == (spix->SR & SPI_SR_RXWNE));}
__STATIC_INLINE void spi_send(SPI_TypeDef *spix, uu08 dat) {spix->TXDR = dat;}
__STATIC_INLINE int is_spi_tx_full(SPI_TypeDef *spix) { return ((spix->SR & SPI_SR_TXC) == 0);}
__STATIC_INLINE int is_spi_tx_empty(SPI_TypeDef *spix) { return (spix->SR & SPI_SR_TXC); }
__STATIC_INLINE uu08 spi_read(SPI_TypeDef *spix) {return spix->RXDR;}

/*****************************************************************************
 * @brief   spi data read.
 *****************************************************************************/
uint8_t nor_spi_rb(void)
{
	HAL_StatusTypeDef err;
	
	uu08 rd;
	

	err = HAL_SPI_Receive(&hspi1, &rd, 1, 10);
	
	dbg_trace_nzero(err, "spi rx fail");
	
	// read data
	return rd;
}

void nor_spi_wb(uint8_t dataW)
{
	HAL_StatusTypeDef err;
	
	err = HAL_SPI_Transmit(&hspi1, &dataW, 1, 10);
	
	dbg_trace_nzero(err, "spi tx fail");
}

/*****************************************************************************
 * @brief   spi data write.
 *****************************************************************************/
uint8_t nor_spi_write(const uint8_t *dataw, uint32_t Len)
{
	HAL_SPI_Transmit(&hspi1, dataw, Len, 100);

	
	
	return (0);
}

/*****************************************************************************
 * @brief   spi data read.
 *****************************************************************************/
uint8_t nor_spi_read(uint8_t *datar, uint32_t Len)
{
	HAL_SPI_Receive(&hspi1, datar, 1, 100);

	return 0;
}

/*****************************************************************************
 * @brief   qpi data write.
 *****************************************************************************/
uint8_t nor_qpi_write(const uint8_t *dataw, uint32_t Len)
{
	return (0);
}

/*****************************************************************************
 * @brief   qpi data read.
 *****************************************************************************/
uint8_t nor_qpi_read(uint8_t *datar, uint32_t Len)
{
	return (0);
}

/*****************************************************************************
 * @brief   nor spi
 *****************************************************************************/
const spi_flash_hal_type spi_nor = {
	//* extern api
	.cs = nor_spi_cs,
	.mode_spi = nor_hal_mode_spi,
	.mode_qpi_out = nor_hal_mode_qpi_out,
	.mode_qpi_in = nor_hal_mode_qpi_in,
	.spi_rb = nor_spi_rb,
	.spi_wb = nor_spi_wb,
	.spi_write = nor_spi_write,
	.spi_read = nor_spi_read,
	.qpi_write = nor_qpi_write,
	.qpi_read = nor_qpi_read,
};

/*****************************************************************************
 * @brief   falsh api.
 * @param   st
 * @return  none
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
uint8_t ext_flash_sector_erase(uint32_t addr)
{
	uint8_t st;

	osMutexWait(os_obj.mid_q25, INT32_MAX);

	st = nor_sector_erase(addr);

	osMutexRelease(os_obj.mid_q25);

	return st;
}

uint8_t ext_flash_block_erase(uint32_t addr)
{
	uint8_t st;

	osMutexWait(os_obj.mid_q25, INT32_MAX);

	st = nor_block_erase(addr);

	osMutexRelease(os_obj.mid_q25);

	return st;
}

uint8_t ext_flash_read(uint32_t addr, int32_t Len, uint8_t *Des)
{
	uint8_t st;

	osMutexWait(os_obj.mid_q25, INT32_MAX);

	st = nor_read(addr, Len, Des);

	osMutexRelease(os_obj.mid_q25);

	return st;
}

uint8_t ext_flash_write_multi(uint32_t addr, int32_t Len, const uint8_t *Src)
{
	uint8_t st;

	osMutexWait(os_obj.mid_q25, INT32_MAX);

	st = nor_write_multi(addr, Len, Src);

	osMutexRelease(os_obj.mid_q25);

	return st;
}
